package com.custom.base.manager

import com.custom.base.manager.SDSelectManager.Mode.SINGLE_MUST_ONE_SELECTED
import java.util.*

/**
 * 选择管理器
 * @param <T>
</T> */
class SDSelectManager<T> {
    private var mListItem: MutableList<T> = ArrayList()
    //获得选中项的位置(单选模式)
    var selectedIndex = -1
    var lastIndex = -1
    private val mMapSelectedIndexItem: MutableMap<Int, T> = LinkedHashMap()
    private var listener: SDSelectManagerListener<T>? = null
    /**
     * 是否开启了管理功能，默认true，开启
     * @return
     */
    var isEnable = true
        set(value) {field = value}
        get() = field

    /**
     * 设置选中模式
     * @param mode
     */
    var mMode = SINGLE_MUST_ONE_SELECTED
        get() = field
        set(mode) {
            clearSelected()
            field = mode
        }

    /**
     * 是否单选模式
     * @return
     */
    val isSingleMode: Boolean
        get() {
            return when (mMode) {
                Mode.SINGLE, SINGLE_MUST_ONE_SELECTED -> true
                Mode.MULTI, Mode.MULTI_MUST_ONE_SELECTED -> false
            }
        }

    /**
     * 项是否被选中
     * @param item
     * @return
     */
    fun isSelected(item: T): Boolean {
        val index = indexOfItem(item)
        return isSelected(index)
    }

    /**
     * 项是否被选中
     * @param index
     * @return
     */
    fun isSelected(index: Int): Boolean {
        var selected = false
        if (index >= 0) {
            when (mMode) {
                Mode.SINGLE, SINGLE_MUST_ONE_SELECTED -> if (index == selectedIndex) {
                    selected = true
                }
                Mode.MULTI, Mode.MULTI_MUST_ONE_SELECTED -> if (mMapSelectedIndexItem.containsKey(index)) {
                    selected = true
                }
            }
        }
        return selected
    }

    /**
     * 获得选中项(单选模式)
     * @return
     */
    val selectedItem: T? get() = getItem(selectedIndex)

    /**
     * 获得选中项的位置(多选模式)
     * @return
     */
    val selectedIndexs: List<Int>
        get() {
            val listIndex: MutableList<Int> = ArrayList()
            if (mMapSelectedIndexItem.isNotEmpty()) {
                for ((key) in mMapSelectedIndexItem) {
                    listIndex.add(key)
                }
            }
            return listIndex
        }

    /**
     * 获得选中项(多选模式)
     * @return
     */
    val selectedItems: List<T>
        get() {
            val listItem: MutableList<T> = ArrayList()
            if (mMapSelectedIndexItem.isNotEmpty()) {
                for ((_, value) in mMapSelectedIndexItem) {
                    listItem.add(value)
                }
            }
            return listItem
        }

    /**
     * 设置监听对象
     * @param listener
     */
    fun setListener(listener: SDSelectManagerListener<T>) {
        this.listener = listener
    }

    /**
     * 设置数据
     */
    fun setItems(items: Array<T>?) {
        val listItem: MutableList<T> = ArrayList()
        if (items != null && items.isNotEmpty()) {
            for (i in items.indices) {
                listItem.add(items[i])
            }
        }
        setItems(listItem)
    }

    /**
     * 设置数据
     */
    fun setItems(items: MutableList<T>?) {
        if (items != null) {
            mListItem = items
        } else {
            mListItem.clear()
        }
        resetIndex()
        initItems(mListItem)
    }

    /**
     * 添加数据
     */
    fun appendItems(items: Array<T>?, addAll: Boolean) {
        val listItem: MutableList<T> = ArrayList()
        if (items != null && items.isNotEmpty()) {
            for (i in items.indices) {
                listItem.add(items[i])
            }
        }
        appendItems(listItem, addAll)
    }

    /**
     * 添加数据
     */
    fun appendItems(
        items: MutableList<T>?,
        addAll: Boolean
    ) {
        if (items != null && items.isNotEmpty()) {
            if (mListItem.isNotEmpty()) {
                if (addAll) {
                    mListItem.addAll(items)
                }
                initItems(items)
            } else {
                setItems(items)
            }
        }
    }

    /**
     * 添加数据
     */
    fun appendItem(item: T?, add: Boolean) {
        if (mListItem.isNotEmpty() && item != null) {
            if (add) {
                mListItem.add(item)
            }
            initItem(indexOfItem(item), item)
        }
    }

    /**
     * 初始数据
     */
    private fun initItems(items: List<T>?) {
        if (items != null && items.isNotEmpty()) {
            var item: T? = null
            var index = 0
            for (i in items.indices) {
                item = items[i]
                index = indexOfItem(item)
                initItem(index, item)
            }
        }
    }

    /**
     * 设置数据后会遍历调用此方法对每个数据进行初始化
     *
     * @param index
     * @param item
     */
    protected fun initItem(index: Int, item: T?) {}

    private fun resetIndex() {
        when (mMode) {
            Mode.SINGLE, SINGLE_MUST_ONE_SELECTED -> selectedIndex = -1
            Mode.MULTI, Mode.MULTI_MUST_ONE_SELECTED -> mMapSelectedIndexItem.clear()
        }
    }

    private fun isIndexLegal(index: Int): Boolean {
        return index >= 0 && index < mListItem.size
    }

    /**
     * 设置最后一次选中的位置选中(单选模式)
     */
    fun selectLastIndex() {
        setSelected(this.lastIndex, true)
    }

    /**
     * 选中全部(多选模式)
     */
    fun selectAll() {
        for (i in mListItem.indices) {
            setSelected(i, true)
        }
    }

    /**
     * 模拟点击该项
     *
     * @param index
     */
    fun performClick(index: Int) {
        if (isIndexLegal(index)) {
            val selected = isSelected(index)
            setSelected(index, !selected)
        }
    }

    /**
     * 模拟点击该项
     *
     * @param item
     */
    fun performClick(item: T) {
        performClick(indexOfItem(item))
    }

    /**
     * 设置该项的选中状态
     *
     * @param item
     * @param selected
     */
    fun setSelected(item: T, selected: Boolean) {
        val index = indexOfItem(item)
        setSelected(index, selected)
    }

    /**
     * 设置该位置的选中状态
     *
     * @param index
     * @param selected
     */
    fun setSelected(index: Int, selected: Boolean) {
        if (!isEnable) {
            return
        }
        if (!isIndexLegal(index)) {
            return
        }
        when (mMode) {
            SINGLE_MUST_ONE_SELECTED -> if (selected) {
                if (selectedIndex == index) {
                } else {
                    val tempCurrentIndex = selectedIndex
                    selectedIndex = index
                    normalItem(tempCurrentIndex)
                    selectItem(selectedIndex)
                    this.lastIndex = selectedIndex
                }
            } else {
                if (selectedIndex == index) {
                } else {
                }
            }
            Mode.SINGLE -> if (selected) {
                if (selectedIndex == index) {
                } else {
                    val tempCurrentIndex = selectedIndex
                    selectedIndex = index
                    normalItem(tempCurrentIndex)
                    selectItem(selectedIndex)
                    this.lastIndex = selectedIndex
                }
            } else {
                if (selectedIndex == index) {
                    val tempCurrentIndex = selectedIndex
                    selectedIndex = -1
                    normalItem(tempCurrentIndex)
                } else {
                }
            }
            Mode.MULTI_MUST_ONE_SELECTED -> if (selected) {
                if (mMapSelectedIndexItem.containsKey(index)) {
                } else {
                    mMapSelectedIndexItem[index] = getItem(index)
                    selectItem(index)
                }
            } else {
                if (mMapSelectedIndexItem.containsKey(index)) {
                    if (mMapSelectedIndexItem.size == 1) {
                    } else {
                        mMapSelectedIndexItem.remove(index)
                        normalItem(index)
                    }
                } else {
                }
            }
            Mode.MULTI -> if (selected) {
                if (mMapSelectedIndexItem.containsKey(index)) {
                } else {
                    mMapSelectedIndexItem[index] = getItem(index)
                    selectItem(index)
                }
            } else {
                if (mMapSelectedIndexItem.containsKey(index)) {
                    mMapSelectedIndexItem.remove(index)
                    normalItem(index)
                } else {
                }
            }
            else -> {
            }
        }
    }

    private fun normalItem(index: Int) {
        if (isIndexLegal(index)) {
            notifyNormal(index, getItem(index))
        }
    }

    /**
     * 选中tiem
     */
    private fun selectItem(index: Int) {
        if (isIndexLegal(index)) {
            notifySelected(index, getItem(index))
        }
    }

    protected fun notifyNormal(index: Int, item: T?) {
        listener?.onNormal(index, item)
    }

    protected fun notifySelected(index: Int, item: T?) {
        listener?.onSelected(index, item)
    }

    /**
     * 获得该位置的item
     *
     * @param index
     * @return
     */
    fun getItem(index: Int): T {
        return mListItem[index]
    }

    /**
     * 返回item的位置
     *
     * @param item
     * @return
     */
    fun indexOfItem(item: T?): Int {
        var index = -1
        if (item != null) {
            index = mListItem.indexOf(item)
        }
        return index
    }

    /**
     * 清除选中
     */
    fun clearSelected() {
        when (mMode) {
            Mode.SINGLE, SINGLE_MUST_ONE_SELECTED -> if (selectedIndex >= 0) {
                val tempCurrentIndex = selectedIndex
                resetIndex()
                normalItem(tempCurrentIndex)
            }
            Mode.MULTI, Mode.MULTI_MUST_ONE_SELECTED -> {
                val listIndexs = selectedIndexs
                for (index in listIndexs) {
                    mMapSelectedIndexItem.remove(index)
                    normalItem(index)
                }
                resetIndex()
            }
            else -> {
            }
        }
    }

    /**
     * 是否全部选中
     */
    fun isSelectAll(): Boolean {
        var isAllSelect = true
        for (t in mListItem) {
            if(!isSelected(t)){
                isAllSelect = false
                break
            }
        }
        return isAllSelect
    }
    /**
     * 是否选中其中一个
     */
    fun isSelectOne(): Boolean {
        var isSelect = false
        for (t in mListItem) {
            if(isSelected(t)){
                isSelect = true
                break
            }
        }
        return isSelect
    }

    interface SDSelectManagerListener<T>{
        fun onNormal(index: Int, item: T?)
        fun onSelected(index: Int, item: T?)
    }

    enum class Mode {
        /**
         * 单选，必须选中一项
         */
        SINGLE_MUST_ONE_SELECTED,

        /**
         * 单选，可以一项都没选中
         */
        SINGLE,

        /**
         * 多选，必须选中一项
         */
        MULTI_MUST_ONE_SELECTED,

        /**
         * 多选，可以一项都没选中
         */
        MULTI
    }
}